﻿

namespace Patterns4Net.Tests.ArchitectureExplorer.ViewModels.Graph
{
    using System.Linq;
    using NUnit.Framework;
    using Patterns4Net.ArchitectureExplorer.Diagram.Relations;
    using Attributes;
    using Attributes.Relations;
    using Diagram;
    
    [TestFixture]
    public class GraphFactoryCreateGraphForPackageTest : GraphViewModelFactoryTestBase
    {
        [SetUp]
        protected override void SetUp()
        {
            base.SetUp();
        }

        [Test]
        public void LowLevel_TypeInfo_Is_Hidden()
        {
            var diagramBuilder = new DiagramBuilder();
            diagramBuilder.AddLayer("test-layer")
                .AddPackage("test-package")
                .Add("classA", AbstractionLevel.Normal)
                .Add("classB", AbstractionLevel.Higher)
                .Add("classC", AbstractionLevel.Low);
            var diagram = diagramBuilder.Build();
            var viewModel = this.CreateDiagramViewModel(diagram);

            var result = this.GraphsFactory.CreateGraphForPackage(viewModel, diagram.GetPackage("test-package"));

            new GraphViewModelAssert(result)
                .HasSubGraph("test-package")
                .HasVertex("classA")
                .HasVertex("classB");
        }

        [Test]
        public void LowLevel_Type_Info_Is_Shown_When_There_Is_No_High_Level_One()
        {
            var diagramBuilder = new DiagramBuilder();
            diagramBuilder.AddLayer("test-layer")
                .AddPackage("test-package")
                .Add("classA", AbstractionLevel.Normal)
                .Add("classB", AbstractionLevel.Normal)
                .Add("classC", AbstractionLevel.Low);
            var diagram = diagramBuilder.Build();
            var viewModel = this.CreateDiagramViewModel(diagram);

            var result = this.GraphsFactory.CreateGraphForPackage(viewModel, diagram.GetPackage("test-package"));

            new GraphViewModelAssert(result)
                .HasSubGraph("test-package")
                .HasVertex("classA")
                .HasVertex("classC")
                .HasVertex("classB");            
        }

        [Test]
        public void Relations_With_LowLevel_Class_Are_Removed_When_High_Level_Class_Is_Present()
        {
            var diagramBuilder = new DiagramBuilder();
            diagramBuilder.AddLayer("test-layer")
                .AddPackage("test-package")
                .Add("classA", AbstractionLevel.Higher)
                .Add("classB", AbstractionLevel.Normal)
                .Add("classC", AbstractionLevel.Low);
            var diagram = diagramBuilder.Build();
            diagram.AddInheritance("classA", "classB");
            diagram.AddComposition("classA", "classC");
            diagram.AddComposition("classC", "classB");
            var viewModel = this.CreateDiagramViewModel(diagram);

            var result = this.GraphsFactory.CreateGraphForPackage(viewModel, diagram.GetPackage("test-package"));

            new GraphViewModelAssert(result)
                .HasSubGraph("test-package")
                .HasVertex("classA")
                .HasVertex("classB");
            new GraphViewModelAssert(result).HasRelation<Inheritance>("classA", "classB");
        }

        [Test]
        public void Mergeable_Relation_InBoth_Directions_Are_Merged()
        {
            var diagramBuilder = new DiagramBuilder();
            diagramBuilder.AddLayer("test-layer")
                .AddPackage("test-package")
                .Add("classA", AbstractionLevel.Normal)
                .Add("classB", AbstractionLevel.Normal)
                .Add("classC", AbstractionLevel.Low);
            var diagram = diagramBuilder.Build();
            diagram.AddComposition("classA", "classB");
            diagram.AddComposition("classB", "classA", Cardinality.Multiple);

            var viewModel = this.CreateDiagramViewModel(diagram);

            var result = this.GraphsFactory.CreateGraphForPackage(viewModel, diagram.GetPackage("test-package"));

            new GraphViewModelAssert(result)
                .HasSubGraph("test-package")
                .HasVertex("classA")
                .HasVertex("classB");
            new GraphViewModelAssert(result).HasRelation<Composition>("classA", "classB", true);
        }
    }
}
